#include <common.h>
#include <asm/arch/hardware.h>
#include <asm/io.h>
#include <asm/arch/sprd_reg.h>

#define PWM_INDEX  0
#define PWM_INDEX2  1

/*r3p0*/

#define PWM_PRESCALE	(0x0000)
#define PWM_MOD		(0x0004)
#define PWM_DUTY		(0x0008)
#define PWM_DIV			(0x000c)
#define PWM_PAT_LOW	(0x0010)
#define PWM_PAT_HIGH	(0x0014)
#define PWM_ENABLE 	(0x0018)
#define PWM_VERSION	(0x001c)

#define PWM2_SCALE		0x0
#define PWM_MOD_MAX 0xff
#define PWM_REG_MSK 0xffff

#ifdef CONFIG_SPI_FPGA
extern bool dual_lcd_display;
#endif

static inline uint32_t pwm_read(int index, uint32_t reg)
{
	return __raw_readl(CTL_BASE_PWM + index * 0x20 + reg);
}

static void pwm_write(int index, int index2, uint32_t value, uint32_t reg)
{
	__raw_writel(value, CTL_BASE_PWM + index * 0x20 + reg);
        if(index != index2)
	__raw_writel(value, CTL_BASE_PWM + index2 * 0x20 + reg);
}

static void __raw_bits_or(unsigned int v, unsigned int a)
{
	__raw_writel((__raw_readl(a) | v), a);
}

void set_backlight(uint32_t brightness)
{
#ifndef CONFIG_FPGA
	int index = PWM_INDEX;
	int index2 = PWM_INDEX2;

#ifdef CONFIG_SPI_FPGA
	if (!dual_lcd_display)
		index2 = PWM_INDEX;
#endif

	__raw_bits_or((0x1 << 0), REG_AON_CLK_CORE_CGM_PWM0_CFG + index * 4);//ext_26m select
	__raw_bits_or((0x1 << 0), REG_AON_CLK_CORE_CGM_PWM0_CFG + index2 * 4);//ext_26m select
	__raw_bits_or(((1 << PWM_INDEX | 1 << PWM_INDEX2) << 4), REG_AON_APB_APB_EB0); //PWMx EN

	if (0 == brightness) {
		pwm_write(index, index2, 0, PWM_ENABLE);
		printf("sprd dual backlight power off. pwm_index=%d pwm_index2=%d brightness=%d\n", index, index2, brightness);
	} else {
		pwm_write(index, index2, PWM2_SCALE, PWM_PRESCALE);
		pwm_write(index, index2, PWM_MOD_MAX, PWM_MOD);
		pwm_write(index, index2, brightness, PWM_DUTY);

		pwm_write(index, index2, PWM_REG_MSK, PWM_PAT_LOW);
		pwm_write(index, index2, PWM_REG_MSK, PWM_PAT_HIGH);
		pwm_write(index, index2, 1, PWM_ENABLE);
		printf("sprd dual backlight power on. pwm_index=%d pwm_index2=%d brightness=%d\n", index, index2, brightness);
	}
#endif
	return;
}
